/**
 * 
 */

/**
 * An enumeration introducing different scales to
 * express the temperature.
 * 		In its current form, the class only supports 
 * 		Celcius, Fahrenheit and Kelvin
 * 
 * @version 1.2
 * @author Inge Gielis
 * @author Gerlinde Van Roey
 */
public enum TemperatureScale {
	
	CELCIUS, FAHRENHEIT, KELVIN;
	
	/**
	 * Return the value of the temperature in the other scale.
	 * @param temperature
	 * 			The temperature to convert.
	 * @param currentScale
	 * 			The currently used temperature scale
	 * @param newScale
	 * 			The temperature scale to convert to
	 * @return The resulting temperature is effective.
	 * 			| result != null
	 * @return The value of the temperature for the new scale.
	 * 			| this.temperature = convertTo(result, newScale, currentScale)
	 * @throws AddOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 * @throws TimesOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 * @throws IllegalArgumentException
	 * 			At least one of the given temperature scales is not effective.
	 * 			| (currentScale == null)||(newScale == null)
	 */
	public static double convertTo(double temperature, TemperatureScale currentScale, TemperatureScale newScale)
				throws AddOverflowException, TimesOverflowException, IllegalArgumentException{
		if((currentScale == null)||(newScale == null)){
			throw new IllegalArgumentException("Non effective temperature scale"); 
		}
		if (currentScale == CELCIUS){
			if (newScale==TemperatureScale.FAHRENHEIT)
				return convertCelciusToFahrenheit(temperature);
			if (newScale==TemperatureScale.KELVIN)
				return convertCelciusToKelvin(temperature);
			return temperature;
		}
		if (currentScale == FAHRENHEIT){
			if (newScale==CELCIUS)
				return convertFahrenheitToCelcius(temperature);
			if (newScale==KELVIN)
				return convertFahrenheitToKelvin(temperature);
			return temperature;
		}
		if (currentScale == KELVIN){
			if(newScale==CELCIUS)
				return convertKelvinToCelcius(temperature);
			if(newScale==KELVIN)
				return convertKelvinToFahrenheit(temperature);
			return temperature;
		}
		// This line will never be reached, each valid temperaturescale has a return statement.
		return -1;	
	}
	
	/**
	 * Return the temperature in degrees Fahrenheit.
	 * @param celciusTemperature
	 * 			The value for the temperature according to the celcius scale
	 * @return	The temperature according to the Fahrenheit scale.
	 * @throws AddOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 * @throws TimesOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 */
	private static double convertCelciusToFahrenheit (double celciusTemperature) throws AddOverflowException, TimesOverflowException{
		double newTemperature = ExtMath.times(celciusTemperature, 1.8);
		newTemperature = ExtMath.add(newTemperature, 32);
		return newTemperature;	
	}
	
	/**
	 * Return the temperature in Kelvin.
	 * @param celciusTemperature
	 * 			The value for the temperature according to the celcius scale
	 * @return	The temperature according to the Kelvin scale.
	 * @throws AddOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 * @throws TimesOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 */
	private static double convertCelciusToKelvin(double celciusTemperature) throws AddOverflowException{
		double newTemperature = ExtMath.add(celciusTemperature, 273.15);
		return newTemperature;	
	}
	
	/**
	 * Return the temperature in degrees Celcius.
	 * @param fahrenheitTemperature
	 * 			The value for the temperature according to the Fahrenheit scale
	 * @return	The temperature according to the Celcius scale.
	 * @throws AddOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 * @throws TimesOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 */
	private static double convertFahrenheitToCelcius(double fahrenheitTemperature) throws TimesOverflowException, AddOverflowException{
		double newTemperature = ExtMath.add(fahrenheitTemperature, -32);
		newTemperature = ExtMath.times(newTemperature, 5/9);
		return newTemperature;
	}
	
	/**
	 * Return the temperature in degrees Kelvin.
	 * @param fahrenheitTemperature
	 * 			The value for the temperature according to the fahrenheit scale
	 * @return	The temperature according to the Kelvin scale.
	 * @throws AddOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 * @throws TimesOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 */
	private static double convertFahrenheitToKelvin(double fahrenheitTemperature) throws AddOverflowException, TimesOverflowException{
		double newTemperature = ExtMath.add(fahrenheitTemperature, 459.67);
		newTemperature = ExtMath.times(newTemperature, 5/9);
		return newTemperature;
	}
	
	/**
	 * Return the temperature in degrees Celcius.
	 * @param kelvinTemperature
	 * 			The value for the temperature according to the Kelvin scale
	 * @return	The temperature according to the Celcius scale.
	 * @throws AddOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 * @throws TimesOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 */
	private static double convertKelvinToCelcius(double kelvinTemperature) throws AddOverflowException{
		double newTemperature = ExtMath.add(kelvinTemperature, -273.15);
		return newTemperature;
	}
	
	/**
	 * Return the temperature in degrees Fahrenheit.
	 * @param kelvinTemperature
	 * 			The value for the temperature according to the Kelvin scale
	 * @return	The temperature according to the Fahrenheit scale.
	 * @throws AddOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 * @throws TimesOverflowException
	 * 			The given temperature is to high, converting the temperature would cause overflow.
	 */
	private static double convertKelvinToFahrenheit(double kelvinTemperature) throws TimesOverflowException, AddOverflowException{
		double newTemperature = ExtMath.times(kelvinTemperature, 1.8);
		newTemperature = ExtMath.add(newTemperature, -459.67);
		return newTemperature;
	}
}
